#include "traitement.h"

#include <QtCore/QFile>

static const QString GoldocheFrameFileName("goldoche_frame_file");

Traitement::Traitement()
 : mBrightnessLevel(100), mContrastLevel(1.0), mFrameData(0), mFrameDataSize(0)
{
	mConvolution[0] = 0;
	mConvolution[1] = 0;
	mConvolution[2] = 0;
	mConvolution[3] = 0;
	mConvolution[4] = 1;
	mConvolution[5] = 0;
	mConvolution[6] = 0;
	mConvolution[7] = 0;
	mConvolution[8] = 0;

	mActiveConvo = 0;

}

void Traitement::openFrame()
{
	QFile *mmf = new QFile(GoldocheFrameFileName);

	if( mmf->open(QFile::ReadWrite) )
	{
		mFrameData = mmf->map(0, mmf->size());
		mFrameDataSize = mmf->size();

		if( mFrameData )
		{
			qDebug("MMF is opened");
		}

		mmf->close();
	}
}

void Traitement::apply()
{
	if( mFrameData )
	{
		qDebug("apply");
		applyBrightness();
		applyContrast();
		if(mActiveConvo != 0)
		{
			applyConvolution();
		}

	}
}

void Traitement::applyBrightness()
{
	for(unsigned int pixelIndex=0; pixelIndex < mFrameDataSize; pixelIndex++)
	{
		int currentPixel = mFrameData[pixelIndex];
		currentPixel = currentPixel + mBrightnessLevel;

		if( currentPixel > 255 )
		{
			currentPixel = 255;
		}
		else if( currentPixel < 0 )
		{
			currentPixel = 0;
		}

		mFrameData[pixelIndex] = static_cast<unsigned char>(currentPixel);
	}
}

void Traitement::applyContrast()
{
	for(unsigned int pixelIndex=0; pixelIndex < mFrameDataSize; pixelIndex++)
	{
		int currentPixel = mFrameData[pixelIndex];
		currentPixel = static_cast<int>( static_cast<double>(currentPixel) * mContrastLevel );

		if( currentPixel > 255 )
		{
			currentPixel = 255;
		}
		else if( currentPixel < 0 )
		{
			currentPixel = 0;
		}

		mFrameData[pixelIndex] = static_cast<unsigned char>(currentPixel);
	}

}
void Traitement::applyConvolution()
{

	unsigned int Ligne = ((mWidth * 24 + 31) & ~31) >> 3;
	unsigned int Colone = mFrameDataSize / Ligne;
	double PixelTemp;
	std::vector<char> CopyTrame;

	for(int i = 1; i < Colone -1; i++)
	{
		for(int j=1; j < Ligne -1; j++)
		{

			PixelTemp = mFrameData[i*Ligne+j]* mConvolution[4] +
						mFrameData[i*Ligne+(j-1)]* mConvolution[3] +
						mFrameData[(i-1)*Ligne+j]* mConvolution[1] +
						mFrameData[(i+1)*Ligne+j]* mConvolution[7] +
						mFrameData[i*Ligne+j+1]* mConvolution[5] +
						mFrameData[(i+1)*Ligne+j+1]* mConvolution[8] +
						mFrameData[(i-1)*Ligne+j+1]* mConvolution[2] +
						mFrameData[(i-1)*Ligne+j-1]* mConvolution[0] +
						mFrameData[(i+1)*Ligne+j-1]* mConvolution[6];

			if (PixelTemp > 255)
				PixelTemp = 255;
			else if ( PixelTemp < 0)
				PixelTemp = 0;
			CopyTrame.push_back(PixelTemp);

		}
	}

	int pos=0;
	for(int i = 1; i < Colone -1; i++)
	{
		for(int j=1; j < Ligne -1; j++)
		{
			mFrameData[i*Ligne+j] = CopyTrame[pos];
			pos++;
		}
	}


}
void Traitement::SetBrillanceProprety(int brightnessLevel)
{
	mBrightnessLevel = brightnessLevel;
}

void Traitement::SetContrasteProprety(double contrastLevel)
{
	mContrastLevel = contrastLevel;
}

void Traitement::SetConvolutionProprety(int Convo[9])
{
	mConvolution[0] = Convo[0];
	mConvolution[1] = Convo[1];
	mConvolution[2] = Convo[2];
	mConvolution[3] = Convo[3];
	mConvolution[4] = Convo[4];
	mConvolution[5] = Convo[5];
	mConvolution[6] = Convo[6];
	mConvolution[7] = Convo[7];
	mConvolution[8] = Convo[8];
}

void Traitement::SetWidth(int width)
{
	mWidth = width;
}
void Traitement::SetActiveConvo(int activeConvo)
{
	mActiveConvo = activeConvo;
}
